<%
'######################################################################
'## ab.sc.asp
'## -------------------------------------------------------------------
'## Feature     :   AspBox SC(Script Control) Extensive Class
'## Version     :   v1.0
'## Author      :   Lajox(lajox@19www.com)
'## Update Date :   2012/12/17 8:39
'## Description :   AspBox SC(ScriptControl)脚本执行操作模块
'## 				相关手册请参考: Microsoft ScriptControl 控件使用指南: http://www.setoutsoft.cn/Html/?266.html
'## 				http://hi.baidu.com/xuanxinni/blog/item/a162f52361825a4093580778.html
'## 				21.4 脚本控件参考 - 《VBScript程序员参考手册（第三版）》: http://book.csdn.net/bookfiles/920
'######################################################################

Class Cls_AB_SC

	Private o_ctrl
	Private s_language, s_timeout
	Private b_lang

	Private Sub Class_Initialize()
		b_lang = False
		s_language = "VBScript"
		Init()
	End Sub

	Public Sub Init()
		On Error Resume Next
		'Set o_ctrl = CreateObject("ScriptControl")
		'Set o_ctrl = Server.CreateObject("MSScriptControl.ScriptControl.1")
		Set o_ctrl = Server.CreateObject("MSScriptControl.ScriptControl")
		On Error GoTo 0
	End Sub

	Private Sub Class_Terminate()
		Set o_ctrl = Nothing
	End Sub

	Public Function [New]()
		Set [New] = New Cls_AB_SC
	End Function

	'可选vb和js; [vb:(vb/vbs/vbscript/default) js:(js/jscript/javascript)]
	Public Property Let Lang(ByVal s)
		Select Case LCase(s)
			Case "vbscript","vb","vbs","default","" : s_language = "VBScript"
			Case "javascript","jscript","js" : s_language = "JScript"
			Case "vbscript.encode","vbscriptencode","vbsencode","vbencode", _
				 "vbenc","vben","vbe","vbsenc","vbse","encode","enc" : s_language = "VBScript.Encode"
			Case Else : s_language = "VBScript"
		End Select
		SetLang(s_language)
	End Property
	Public Property Get Lang()
		Lang = getLang_(s_language)
	End Property

	Public Function SetLang(Byval s)
		o_ctrl.Language = getLang_(s)
		b_lang = True
	End Function

	Public Property Let State(ByVal s)
		o_ctrl.State = s
	End Property
	Public Property Get State()
		State = o_ctrl.State
	End Property

	Public Property Let AllowUI(ByVal s)
		o_ctrl.AllowUI = s
	End Property
	Public Property Get AllowUI()
		AllowUI = o_ctrl.AllowUI
	End Property

	Public Property Let SitehWnd(ByVal s)
		o_ctrl.SitehWnd = s
	End Property
	Public Property Get SitehWnd()
		SitehWnd = o_ctrl.SitehWnd
	End Property

	Public Property Let UseSafeSubset(ByVal s)
		o_ctrl.UseSafeSubset = s
	End Property
	Public Property Get UseSafeSubset()
		UseSafeSubset = o_ctrl.UseSafeSubset
	End Property

	'------------------------------------------------------------------------------------------
	'# AAB.Sc.Timeout 属性
	'# @syntax: AB.Sc.Timeout = timeout
	'# @return: Integer (整型)
	'# @dowhat: 控件的执行脚本的超时值
	'#   设置或返回一个数字，代表以毫秒为单位的时间，表示ScriptControl对象在终止长时间运行的脚本之前需要等待的时间长度。
	'#   这个属性可以被设置为常量NoTimeout(-1)，这样脚本代码的执行就没有时间限制；
	'#   但是关闭超时机制是比较危险的，因为可能会有人创建一个包含死循环的脚本。默认的值是10 000ms(10s)。
	'#   超时时间过后，会产生一个Timeout事件(这取决于ScriptControl对象是否能处理事件)，
	'#   同时，如果ScriptControl对象启用了AllowUI属性，就会收到一个对话框警告，允许选择继续执行脚本，
	'#   否则，脚本将中止执行并产生错误。
	'#   如果这个属性被设置为0(不推荐这样做)，只要脚本停止发送Windows消息超过100ms，就会立即产生Timeout事件
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# none
	'------------------------------------------------------------------------------------------

	Public Property Let Timeout(ByVal s)
		s_timeout = s
		o_ctrl.Timeout = s_timeout
	End Property
	Public Property Get Timeout()
		Timeout = o_ctrl.Timeout
	End Property

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.CodeObject
	'# @return: CodeObject对象
	'# @dowhat: 脚本暴露给宿主调用的对象。只读。
	'--DESC-------------------------------------------------------------------------------------
	'# @param : none
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim objSC : Set objSC = AB.Sc.New
	'# objSC.Lang = "vb" '可选: vb/js
	'# objSC.AddCode "Function GetInfo(): " & _
	'# vbNewLine & vbTab & "GetInfo = ""Hello, world.""" & _
	'# vbNewLine & "End Function"
	'# objSC.AddCode "Function TestFunc(a) : " & _
	'# vbNewLine & vbTab & "TestFunc = a * a " & _
	'# vbNewLine & "End Function"
	'# Dim Result1 : Result1 = objSC.Run("TestFunc", 2)
	'# '_下面的脚本片段演示了使用CodeObject方法调用脚本代码
	'# Dim objCodeObject : Set objCodeObject = objSC.CodeObject
	'# Dim Result2 : Result2 = objCodeObject.TestFunc(2)
	'# AB.C.PrintCn Result1
	'# AB.C.PrintCn Result2
	'-------------------------------------------------------------------------------------------

	Public Function CodeObject
		On Error Resume Next
		Set CodeObject = o_ctrl.CodeObject
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Modules
	'# @return: Modules对象
	'# @dowhat: 返回ScriptControl对象的Modules集合的引用
	'#    宿主提供给脚本的组件库模块。只读。
	'#   （COM组件通常都是以对象收集的形式向用户提供可以留给用户二次开发的对象集合，每一个收集即一个Modules）
	'#   1. Modules集合包含一个ScriptControl对象的所有Module对象，包括默认的Global模块。
	'#   对Global模块的成员的调用可以直接通过ScriptControl对象来进行，而不需要遍历Modules集合。
	'#   Global对象还具有一个值与常量GlobalModule相等的索引。
	'#   2. Module对象可以使用Add方法被添加到Modules集合中。
	'#   使用默认的Modules.Item方法可以访问具体的Module对象。
	'#   Count属性提供了集合中Module对象的个数。整个集合可以通过几种方式来遍历，最常用的是使用For Each … Next循环。
	'#   因为不能删除单个模块，所以必须使用ScriptControl对象的Reset方法来删除不想要的模块，该方法将清空整个集合。
	'#   ++++++++++++++  <Modules集合唯一的属性描述>  ++++++++++++++
	'#   Count : 返回值(Long) : 访问方式(只读) : 描述(返回Modules集合中Module对象的个数)
	'#   ++++++++++++++  <Modules集合对象的方法描述>  ++++++++++++++
	'#   Add :
	'#     参  数 (name：字符串值，表示要添加模块的名称；该名称将用作在Modules集合中的索引; module：可选。要被加入集合的Module对象)
	'#     返回值 (如果省略module参数，就返回新的Module对象)
	'#     描  述 (使用这个方法可以在Modules集合中添加一个新的Module对象；
	'#             如果在一个小型的工程中，只包含相对较少的脚本，可能就只需要使用“Global”模块。
	'#             但是如果有很多脚本，那么将它们分别组织到各个模块中是很有好处的——
	'#             尤其是如果需要在不同的模块中重复使用具有相同名称的过程和函数时，就更应该这样做)
	'#   item :
	'#     参  数 (index：一个Long或String类型的值，分别表示一个索引或一个关键字)
	'#     返回值 (如果存在匹配的index，就返回集合中的一个Module对象)
	'#     描  述 (这是集合的默认属性，所以很多程序员都会忽略item方法的实际名称：Set objModule = objSC.Modules("MyModule") )
	'--DESC-------------------------------------------------------------------------------------
	'# @param : none
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim objSC : Set objSC = AB.Sc.New
	'# objSC.Lang = "vb" '可选: vb/js
	'# Dim objModule : Set objModule = objSC.Modules.Add("NewModule")
	'# objModule.AddCode "Function GetInfo(): " & _
	'# vbNewLine & vbTab & "GetInfo = ""Hello, world.""" & _
	'# vbNewLine & "End Function"
	'# objModule.AddCode "Function TestFunc(a) : " & _
	'# vbNewLine & vbTab & "TestFunc = a * a " & _
	'# vbNewLine & "End Function"
	'# Dim Result : Result = objModule.Run("GetInfo")
	'# AB.C.PrintCn Result
	'# '_下面的脚本片段演示了使用Module.CodeObject方法调用模块中的代码
	'# Dim objCodeObject : Set objCodeObject = objModule.CodeObject
	'# Dim lngVal : lngVal = objCodeObject.TestFunc(2)
	'# AB.C.PrintCn lngVal
	'-------------------------------------------------------------------------------------------

	Public Function Modules
		On Error Resume Next
		Set Modules = o_ctrl.Modules
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.GetModule(index)
	'# @return: Module对象
	'# @dowhat: 返回一个已存在的Module对象
	'--DESC-------------------------------------------------------------------------------------
	'# @param index [string] : 表示一个关键字(用于索引), 缺省默认为 "Global"
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim objSC : Set objSC = AB.Sc.New
	'# objSC.Lang = "vb" '可选: vb/js
	'# Dim objModule : Set objModule = objSC.Modules.Add("NewModule")
	'# objModule.AddCode "Function GetInfo(): " & _
	'# vbNewLine & vbTab & "GetInfo = ""Hello, world.""" & _
	'# vbNewLine & "End Function"
	'# Dim Result1 : Result1 = objModule.Run("GetInfo")
	'# Dim newModule : Set newModule = objSC.getModule("NewModule")
	'# Dim Result2 : Result2 = newModule.Run("GetInfo")
	'# AB.C.PrintCn Result1
	'# AB.C.PrintCn Result2
	'-------------------------------------------------------------------------------------------

	Public Function GetModule(Byval index)
		On Error Resume Next
		If IsNull(index) Or Trim(index) = "" Then index = "Global"
		Set GetModule = o_ctrl.Modules(index)
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Module()
	'# @return: 默认的Module对象
	'# @dowhat: 返回默认Module对象（即索引为 "Global" 的 默认Module对象）
	'--DESC-------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim objSC : Set objSC = AB.Sc.New
	'# objSC.Lang = "vb" '可选: vb/js
	'# Dim objModule : Set objModule = objSC.Module
	'# objModule.AddCode "Function Test(): Test = 1001 : End Function"
	'# objModule.AddCode "Function GetInfo(a, b): GetInfo = a + b : End Function"
	'# Dim objCode : Set objCode = objModule.CodeObject
	'# Dim Result1 : Result1 = objModule.Eval("GetInfo(2,5)")
	'# Dim Result2 : Result2 = objModule.Run("GetInfo", 2, 5)
	'# Dim Result3 : Result3 = objCode.GetInfo(2,5)
	'# AB.C.PrintCn objModule.Eval("Test()") '输出: 1001
	'# AB.C.PrintCn objModule.Run("Test") '输出: 1001
	'# AB.C.PrintCn Result1 '输出: 7
	'# AB.C.PrintCn Result2 '输出: 7
	'# AB.C.PrintCn Result3 '输出: 7
	'-------------------------------------------------------------------------------------------

	Public Function [Module]()
		On Error Resume Next
		'Set [Module] = o_ctrl.Modules
		Set [Module] = o_ctrl.Modules("Global")
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Object()
	'# @alias: AB.Sc.ModuleCodeObject()
	'# @alias: AB.Sc.ModuleCode()
	'# @alias: AB.Sc.Mc()
	'# @return: 默认的Module对象
	'# @dowhat: 返回默认Module对象（即索引为 "Global" 的 默认Module对象）
	'--DESC-------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "vb"
	'# Sc.Add "Function Test(a, b) : Test = a + b : End Function"
	'# Dim obj : Set obj = Sc.Object
	'# AB.C.Print obj.Test(2, 5) '输出：7
	'-------------------------------------------------------------------------------------------

	Public Function [Object]()
		On Error Resume Next
		'Set [Object] = o_ctrl.CodeObject
		Set [Object] = Module.CodeObject
		On Error GoTo 0
	End Function
	Public Function ModuleCodeObject():Set ModuleCodeObject = Module.CodeObject:End Function
	Public Function ModuleCode():Set ModuleCode = ModuleCodeObject():End Function
	Public Function MC():Set MC = ModuleCodeObject():End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Procedures
	'# @return: 过程的集合(Object类型)
	'# @dowhat: 返回模块中定义的过程的集合
	'#  $$. Procedures集合(Procedure对象集合)
	'#    1. 返回默认的“Global”模块的Procedure集合的引用。
	'#       要访问其它模块的Procedure集合，可以通过Modules集合直接访问该模块，然后使用Module.Procedure属性
	'#    2. Procedures集合中保存着某一给定的Modules对象的所有过程。它
	'#       为遍历某一给定模块的所有过程并访问其内部代码提供了一种便捷的途径。
	'#       每个过程都是使用Module对象的AddCode方法添加到集合中，而不是直接使用集合操作来进行的。
	'#       同样，某个过程被添加到集合中之后，也无法将其删除，因为Procedures集合没有Remove方法。
	'#   ++++++++++++++  <Procedures集合对象唯一的属性>  ++++++++++++++
	'#   Count : 返回值(Long) : 访问方式(只读) : 描述(返回Procedures集合中Procedure对象的个数)
	'#   ++++++++++++++  <Procedures集合对象的方法描述>  ++++++++++++++
	'#    Procedures集合对象没有任何方法
	'#  $$. Procedure对象
	'#    1. Procedure对象定义了代码的一个逻辑单元，在VBScript中可以是一个Sub或一个Function。
	'#       Procedure对象包含了很多有用的属性，使您能够检查过程名、参数个数以及过程是否具有返回值。
	'#       脚本代码的入口也是由Procedure对象提供的。
	'#    2. 注意，Procedures集合没有Add方法，但可以使用AddCode方法给模块添加新的方法，
	'#       这样就会隐式地创建一个Procedure对象并添加到集合中。
	'#   ++++++++++++++  <Procedure对象的属性描述>  ++++++++++++++
	'#   hasReturnValue : 返回值(Boolean) : 访问方式(只读) : 描述(返回过程是否有返回值(换句话说，是一个过程还是一个函数))
	'#   Name : 返回值(String) : 访问方式(只读) :
	'#          描述(Procedure对象的名称，应该和对象中包含的某个实际的过程或函数名相同。
	'#               这个名称还用作在Procedures集合的索引。
	'#               如果使用AddCode方法在模块中添加另一个同名过程，新的过程就会覆盖模块中原来的过程)
	'#   NumArgs : 返回值(Long) : 访问方式(只读) : 描述(返回Procedure对象中过程或函数接收参数的个数)
	'#   ++++++++++++++  <Procedure对象的方法描述>  ++++++++++++++
	'#   item :
	'#     参  数 (index：一个Long或String类型的值，分别表示一个索引或一个关键字)
	'#     返回值 (如果存在匹配的index，就返回集合中的一个Module对象)
	'#     描  述 (这是集合的默认属性，所以很多程序员都会忽略item方法的实际名称：Set objProc = objMod.Procedure("MyProc") )
	'--DESC-------------------------------------------------------------------------------------
	'# @param : none
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim objSC : Set objSC = AB.Sc.New
	'# objSC.Lang = "vb" '可选: vb/js
	'# objSC.AddCode "Function GetInfo(): " & _
	'# vbNewLine & vbTab & "GetInfo = ""Hello, world.""" & _
	'# vbNewLine & "End Function"
	'# objSC.AddCode "Function TestFunc(a) : " & _
	'# vbNewLine & vbTab & "TestFunc = a * a " & _
	'# vbNewLine & "End Function"
	'# AB.C.PrintCn "共有" & objSC.Procedures.Count & "个Procedure对象"
	'# '_下面的脚本片段使用For Each … Next循环语法遍历Procedures集合
	'# Dim objProcedure, strList
	'# For Each objProcedure In objSC.Procedures
	'# strList = strList & "Name: " & objProcedure.Name
	'# strList = strList & vbNewLine & vbTab
	'# strList = strList & "Argument Count: " & objProcedure.NumArgs
	'# strList = strList & vbNewLine & vbTab
	'# strList = strList & "Has Return: " & objProcedure.HasReturnValue
	'# strList = strList & vbNewLine & vbNewLine & "<br>"
	'# Next
	'# AB.C.PrintCn strList
	'-------------------------------------------------------------------------------------------

	Public Function Procedures
		On Error Resume Next
		Set Procedures = o_ctrl.Procedures
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Error
	'# @return: Error对象
	'# @dowhat: 错误对象，发生错误时，此属性返回一个错误对象
	'#   Error对象提供与脚本控件相关联的语法和运行时错误信息。
	'#   虽然Error对象提供的信息和VB、VBScript中Err对象提供的信息类似，
	'#   但在诊断脚本相关的问题时，有一些很有价值的额外属性(Column、Text、Line)。
	'#   虽然在VB中也能够声明和初始化Error对象，但是一般还是通过ScriptControl对象直接访问Error对象的成员。
	'--DESC-------------------------------------------------------------------------------------
	'# @param : none
	'--DEMO-------------------------------------------------------------------------------------
	'# On Error Resume Next
	'# AB.Use "Sc"
	'# Dim sc : Set sc = AB.Sc.New
	'# sc.Lang = "vb" '可选: vb/js
	'# Dim strCode
	'# strCode = "Function Test(a) : " & _
	'# vbNewLine & vbTab & "Test = Cstr(a * a) " & _
	'# vbNewLine & "End Function"
	'# sc.AddCode strCode
	'# If sc.Error.Number <> 0 Then
	'# 	With sc.Error
	'# 		AB.C.PrintCn "Error # " & .Number & ": " _
	'# 		& .Description & vbCrLf _
	'# 		& "At Line: " & .Line & " Column: " & .Column _
	'# 		& " : " & .Text & vbTab & "Syntax Error"
	'# 	End With
	'# End If
	'# Dim result : result = sc.Run("Test", _
	'# 2E5)
	'# If sc.Error.Number <> 0 Then
	'# 	With sc.Error
	'# 		AB.C.PrintCn "Error # " & .Number & ": " _
	'# 		& .Description & vbCrLf _
	'# 		& "At Line: " & .Line & " Column: " & .Column _
	'# 		& " : " & .Text & vbTab & "Runtime Error"
	'# 	End With
	'# Else
	'# 	AB.C.PrintCn result
	'# End If
	'-------------------------------------------------------------------------------------------

	Public Function [Error]
		On Error Resume Next
		Set [Error] = o_ctrl.[Error]
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.CodeObjectLoad(path)
	'# @alias: AB.Sc.CodeLoad(path)
	'# @return: Object [返回一个Module.CodeObject]
	'# @dowhat: 往脚本引擎中引入脚本文件里的执行代码并返回CodeObject对象
	'--DESC-------------------------------------------------------------------------------------
	'# @param path 	[string] : 要执行的脚本文件路径
	'--DEMO-------------------------------------------------------------------------------------
	'# '假设 文本文件 “/test/1.txt” 里的代码：
	'#   function test() { var _temp = 'hello world'; return _temp; }
	'#   function jsdata(str) { var _temp = null;
	'#   try { eval('_temp = (' + str + ');'); }
	'#   catch(e) { _temp = null; }
	'#   	return (_temp);
	'#   }
	'# '__使用 CodeLoad 方法载入文件代码：
	'# AB.Use "Sc"
	'# Dim objSc : Set objSc = AB.Sc.New
	'# objSc.Lang = "js"
	'# Dim CodeObject
	'# Set CodeObject = objSc.CodeLoad("/test/1.txt")
	'# Dim temp,obj
	'# temp = "{""color"":""red""}"
	'# Set obj = CodeObject.jsdata(temp)
	'# response.write(obj.color) '输出：red
	'# '__载入多个文件代码：
	'# AB.Use "Sc"
	'# Dim objSc : Set objSc = AB.Sc.New
	'# objSc.Lang = "js"
	'# Dim obj1,obj2,obj3
	'# Set obj1 = objSc.CodeLoad("/jsLib/a.js") '文件1内容: function a() { return 'a'; }
	'# Set obj2 = objSc.CodeLoad("/jsLib/b.js") '文件2内容: function b() { return 'b'; }
	'# Set obj3 = objSc.CodeLoad("/jsLib/c.js") '文件3内容: function c() { return a() + ':' + b(); }
	'# Dim temp1 : temp1 = obj1.a()
	'# Dim temp2 : temp2 = obj2.b()
	'# Dim temp3 : temp3 = obj3.b()
	'# ab.c.print obj3.c() '输出： a:b
	'-------------------------------------------------------------------------------------------

	Public Function CodeObjectLoad(Byval path)
		On Error Resume Next
		Include(path)
		'Dim objModule : Set objModule = Me.Modules.Add("NewModule")
		Dim objModule : Set objModule = Me.GetModule("Global")
		Dim objCodeObject : Set objCodeObject = objModule.CodeObject
		Set CodeObjectLoad = objCodeObject
		On Error GoTo 0
	End Function
	Public Function CodeLoad(Byval path)
		On Error Resume Next:aotoLang():Set CodeLoad = CodeObjectLoad(path):On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Include(path)
	'# @alias: AB.Sc.Inc(path)
	'# @alias: AB.Sc.Import(path)
	'# @return: Object [返回一个Module.CodeObject]
	'# @dowhat: 往脚本引擎中引入脚本文件里的执行代码(可多次引入脚本文件)
	'--DESC-------------------------------------------------------------------------------------
	'# @param path 	[string] : 要执行的脚本文件路径
	'--DEMO-------------------------------------------------------------------------------------
	'# '__载入多个文件代码：
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "js"
	'# Sc.Inc("/jsLib/a.js") '文件1内容: function a() { return 'a'; }
	'# Sc.Inc("/jsLib/b.js") '文件2内容: function b() { return 'b'; }
	'# Sc.Inc("/jsLib/c.js") '文件3内容: function c() { return a() + ':' + b(); }
	'# Dim obj : Set obj = Sc.Object '等同于：Set obj = Sc.Module.CodeObject
	'# Dim temp : temp = obj.c()
	'# ab.c.print temp '输出： a:b
	'-------------------------------------------------------------------------------------------

	Public Function Include(Byval path)
		On Error Resume Next
		aotoLang()
		If Mid(path,2,1)<>":" Then path = Server.MapPath(path)
		Dim code
		'AB.Use "fso"
		'If AB.C.isFile(path) Then code = AB.Fso.Read(path)
		If AB.C.isFile(path) Then code = AB.C.IncRead(path)
		'Dim objModule : Set objModule = Me.Modules.Add("NewModule")
		Dim objModule : Set objModule = Me.GetModule("Global")
		objModule.AddCode code
		On Error GoTo 0
	End Function
	Public Function Inc(Byval path)
		On Error Resume Next:Include(path):On Error GoTo 0
	End Function
	Public Function Import(Byval path)
		On Error Resume Next:Include(path):On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Load(path)
	'# @return: object
	'# @dowhat: 往脚本引擎中引入脚本文件里的执行代码
	'--DESC-------------------------------------------------------------------------------------
	'# @param path 	[string] : 要执行的脚本文件路径
	'--DEMO-------------------------------------------------------------------------------------
	'# '假设 文本文件 “/test/1.txt” 里的代码：
	'#   function test() { var _temp = 'hello world'; return _temp; }
	'#   function jsdata(str) { var _temp = null;
	'#   try { eval('_temp = (' + str + ');'); }
	'#   catch(e) { _temp = null; }
	'#   	return (_temp);
	'#   }
	'# '_使用 Load 方法载入文件代码：
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "js"
	'# 'Sc.Load "/test/1.txt"
	'# Dim jso : Set jso = Sc.Load("/test/1.txt")
	'# Dim temp,obj
	'# temp = "{""color"":""red""}"
	'# 'Set obj = Sc.Eval("jsdata('"& temp &"')")
	'# 'Set obj = Sc.Run("jsdata", temp)
	'# Set obj = jso.jsdata(temp)
	'# response.write(obj.color) '输出：red
	'-------------------------------------------------------------------------------------------

	Public Function [Load](Byval path)
		On Error Resume Next
		'Include(path)
		Set [Load] = CodeObjectLoad(path)
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Add(s)
	'# @return: void
	'# @dowhat: 往脚本引擎中加入要执行的脚本
	'#   这是向脚本控件添加脚本的主要方法。在ScriptControl对象上调用该方法时，会在默认的“Global”模块中自动添加新的代码。
	'#   在单独的Module对象上调用该方法时，会在具体涉及的模块中添加代码。
	'#   添加整个过程的代码或一个代码块时，必须在一次调用AddCode方法时添加所有的代码。
	'#   代码块中的语句之间可以使用冒号(:)隔开，或使用换行符vbNewLine(推荐使用)、vbCr、vbLf和vbCrLf
	'--DESC-------------------------------------------------------------------------------------
	'# @param s   [string] : 要执行的脚本(表示一个合法的脚本)
	'--DEMO-------------------------------------------------------------------------------------
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "js"
	'# Sc.Add "function test() { var _temp = 'hello world'; return _temp; }"
	'# Sc.Add "function jsdata(str) { var _temp = null; try { eval('_temp = (' + str + ');'); } catch(e) { _temp = null; } return (_temp); }"
	'# Dim str,temp,obj
	'# str = Sc.Eval("test()")
	'# response.write(str) & "<br>"
	'# temp = "{""color"":""red""}"
	'# Set obj = Sc.Eval("jsdata('"& temp &"')")
	'# 'Set obj = Sc.Run("jsdata", temp)
	'# response.write(IsObject(obj)) & "<br>"
	'# response.write(TypeName(obj)) & "<br>"
	'# response.write(obj.color)
	'-------------------------------------------------------------------------------------------

	Public Function AddCode(Byval s)
		On Error Resume Next
		aotoLang()
		o_ctrl.addCode(s)
		On Error GoTo 0
	End Function
	Public Function Add(Byval s):AddCode s:End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.addObject(name, obj, bool)
	'# @alias: AB.Sc.addObj(name, obj, bool)
	'# @return: void
	'# @dowhat: 往脚本引擎中加入一个对象，以便在脚本中可以使用该对象提供的方法
	'#  详细参考：《如何使用脚本控件的 AddObject 方法》http://support.microsoft.com/kb/185697
	'--DESC-------------------------------------------------------------------------------------
	'# @param name 	[string] : 要添加对象的唯一的字符串名称
	'# @param obj   [object] : 应用程序范围内的任意对象
	'# @param bool 	[object] : 可选的布尔值，表示对象的公有成员是否能够被ScriptControl对象及其脚本访问(缺省：False)
	'--DEMO-------------------------------------------------------------------------------------
	'# class cls_t: function foo() : foo = "hello" : end function : end class
	'# dim o_t : set o_t = New cls_t
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "vb"
	'# Sc.addObj "ttt", o_t, True
	'# Dim obj : Set obj = Sc.Object
	'# AB.C.PrintCn typeName(obj.ttt) '输出：cls_t
	'# AB.C.PrintCn obj.ttt.foo() '输出：hello
	'-------------------------------------------------------------------------------------------

	Public Function AddObject(Byval name, Byval obj, Byval bool)
		On Error Resume Next
		aotoLang()
		If IsNull(bool) Or Trim(bool)="" Then
			'bool = False
			o_ctrl.addObject name, obj
		Else
			o_ctrl.addObject name, obj, CBool(bool)
		End If
		On Error GoTo 0
	End Function
	Public Function addObj(Byval name, Byval obj, Byval bool):AddObject name, obj, bool:End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.ExecuteStatement(s)
	'# @alias: AB.Sc.Exec(s)
	'# @return: void
	'# @dowhat: 解释并执行脚本语句
	'#   与Eval方法不同，ExecuteStatement只执行一个语句，不返回任何值。
	'#   如果拿Eval和ExecuteStatement方法相比较，会发现“=”操作符在使用Eval时被认为是比较操作符，
	'#   而在使用ExecuteStatement方法时被认为是赋值操作符。
	'#   因此，x=y在使用Eval时得到的是布尔值，而使用ExecuteStatement方法时，y的值将被赋给x，而没有返回值。
	'#   被计算的表达式可以利用Module或ScriptControl对象范围内的任何成员。
	'#   要获取一个过程的返回值，应该使用Eval或Run方法
	'--DESC-------------------------------------------------------------------------------------
	'# @param s   [string] : 脚本语句(表示要执行的字符串语句)
	'--DEMO-------------------------------------------------------------------------------------
	'# '===== VBScript代码实例 ======
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "vb" '可选: vb/js
	'# Sc.Exec "Dim y : y = 100"
	'# 'Sc.Add "Dim y : y = 100"
	'# Sc.Add "y = y + 15"
	'# Dim result
	'# result = Sc.Eval("y * 100")
	'# response.write result
	'# '===== JScript代码实例 1 ======
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "js" '可选: vb/js
	'# Sc.Exec "function test() { return {property: 'test1234'}; };"
	'# 'Sc.Add "function test() { return {property: 'test1234'}; };"
	'# Dim result
	'# Set result = Sc.Eval("test();")
	'# response.write result.property
	'-------------------------------------------------------------------------------------------

	Public Function ExecuteStatement(Byval s)
		On Error Resume Next
		aotoLang()
		o_ctrl.ExecuteStatement(s)
		On Error GoTo 0
	End Function
	Public Function Exec(Byval s):ExecuteStatement s:End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Eval(s)
	'# @return: Anything 表达式的输出(如果有的话)
	'# @dowhat: 表达式求值
	'#   计算一个表达式的值。与VBScript中的Eval函数类似。这是计算您提供的动态表达式最好的方法。
	'#   如果拿Eval和ExecuteStatement方法相比较，会发现“=”操作符在使用Eval时被认为是比较操作符，
	'#   而在使用ExecuteStatement方法时被认为是赋值操作符。
	'#   因此，x=y在使用Eval时得到的是布尔值，而使用ExecuteStatement方法时，y的值将被赋给x，而没有返回值。
	'#   Eval方法可以应用于ScriptControl对象和Module对象，并利用其所有成员
	'--DESC-------------------------------------------------------------------------------------
	'# @param s   [string] : 字符串表达式
	'# 一个字符串值，代表一个合法的“表达式”，表示被编译或执行的脚本片段
	'--DEMO-------------------------------------------------------------------------------------
	'# '===== VBScript代码实例 ======
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "vb" '可选: vb/js
	'# 'Sc.Exec "Dim y : y = 100"
	'# Sc.Add "Dim y : y = 100"
	'# Sc.Add "y = y + 15"
	'# Dim result
	'# result = Sc.Eval("y * 100")
	'# response.write result
	'# '===== JScript代码实例 1 ======
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "js" '可选: vb/js
	'# 'Sc.Exec "function test() { return {property: 'test1234'}; };"
	'# Sc.Add "function test() { return {property: 'test1234'}; };"
	'# Dim result
	'# Set result = Sc.Eval("test();")
	'# response.write result.property
	'# '===== JScript代码实例 2 ======
	'# <script language="JScript" runat="server">
	'# function jsdata(str) {
	'# 	var _temp = null;
	'# 	try {
	'# 		eval("_temp = (" + str.toString() + ");");
	'# 	} catch(e) { _temp = null; }
	'# 	return (_temp);
	'# }
	'# </script>
	'# ＜％
	'# dim aaa,temp
	'# 'aaa = "{""error"":1001}"
	'# aaa = "{error:false}"
	'# set temp = jsdata(aaa)
	'# response.write temp.error
	'# ％＞
	'# '== 上面代码可以写成：
	'# AB.Use "Sc"
	'# Dim Sc : Set Sc = AB.Sc.New
	'# Sc.Lang = "js"
	'# Dim sss
	'# 'sss = "function jsdata(str) { var _temp = null; try { eval('_temp = (' + str + ');'); } catch(e) { _temp = null; } return (_temp); }"
	'# sss = "function jsdata(str) {" & VBCrlf &_
	'# "	var _temp = null;" & VBCrlf &_
	'# "	try {" & VBCrlf &_
	'# "		eval('_temp = (' + str.toString() + ');');" & VBCrlf &_
	'# "	} catch(e) { _temp = null; }" & VBCrlf &_
	'# "	return (_temp);" & VBCrlf &_
	'# "}"
	'# Sc.Add sss
	'# dim aaa,temp
	'# 'aaa = "{""error"":1001}"
	'# aaa = "{error:false}"
	'# Set temp = Sc.Eval("jsdata('"& aaa &"')")
	'# response.write temp.error
	'-------------------------------------------------------------------------------------------

	Public Function Eval(Byval s)
		On Error Resume Next
		aotoLang()
		If IsObject(o_ctrl.Eval(s)) Then
			Set Eval = o_ctrl.Eval(s)
		Else
			Eval = o_ctrl.Eval(s)
		End If
		On Error GoTo 0
	End Function

	'-------------------------------------------------------------------------------------------
	'# AB.Sc.Run(s, param)
	'# @return: 如果调用函数，就返回该函数的返回值
	'# @dowhat: 运行一个指定的过程或函数
	'#   在ScriptControl对象上调用Run()时，该方法将运行“Global”模块中具有给定名称的过程或函数。
	'#   在一个Module对象上调用Run()时，该方法运行模块内具有给定名称的过程或函数。
	'#   也可以使用CodeObject属性直接调用过程和函数
	'--DESC-------------------------------------------------------------------------------------
	'# @param s   	[string] : 过程或函数名(要运行的过程或函数的字符串名称)
	'# @param param   [array]  : 参数数组 或 单个参数形式
	'--DEMO-------------------------------------------------------------------------------------
	'# 基于过程的类型，可以以不同方式调用Run方法，这取决于返回值和参数的情况
	'# AB.Use "Sc"
	'# Dim objSC : Set objSC = AB.Sc.New
	'# objSC.Lang = "vb" '可选: vb/js
	'# Dim strCode
	'# strCode = "Function ManyArg(a,b,c,d): ManyArg = (a * b + c - d)"
	'# strCode = strCode & ": End Function"
	'# objSC.Add strCode
	'# Dim Result
	'# Result = objSC.Run("ManyArg", Array(1, 2, 3, 4) )
	'# ab.c.print Result
	'-------------------------------------------------------------------------------------------

	Public Function Run(Byval s, Byval param)
		On Error Resume Next
		aotoLang()
		Dim i, temp
		If IsArray(param) Then
			For i = 0 To UBound(param)
				If i = 0 Then
					temp = "param("& i &")"
				Else
					temp = temp & ", param("& i &")"
				End If
			Next
			Execute("If IsObject(o_ctrl.Run(s, "& temp &")) Then Set Run = o_ctrl.Run(s, "& temp &") Else Run = o_ctrl.Run(s, "& temp &")")
			Execute("If Err Then : Err.Clear: If IsObject(o_ctrl.Run(s, param)) Then Set Run = o_ctrl.Run(s, param) Else Run = o_ctrl.Run(s, param) : End If")
		Else
			If IsObject(o_ctrl.Run(s, param)) Then Set Run = o_ctrl.Run(s, temp) Else Run = o_ctrl.Run(s, param)
			If Err Then : If IsObject(o_ctrl.Run(s)) Then Set Run = o_ctrl.Run(s) Else Run = o_ctrl.Run(s) : End If
		End If
		On Error GoTo 0
	End Function

	Public Function aotoLang()
		If Not b_lang Then SetLang(s_language)
	End Function

	Private Function getLang_(ByVal s)
		Select Case LCase(s)
			Case "vbscript","vb","vbs","default","" : s = "VBScript"
			Case "javascript","jscript","js" : s = "JScript"
			Case "vbscript.encode","vbscriptencode","vbsencode","vbencode", _
				 "vbenc","vben","vbe","vbsenc","vbse","encode","enc" : s = "VBScript.Encode"
			Case Else : s = "VBScript"
		End Select
		getLang_ = s
	End Function

End Class
%>